<?php
/**
 * DMFramework
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @url http://dmframework.nl
 */

/**
 * The benchmarking class can be used to calculate time and memory usage between
 * two marking points set by the user.
 * 
 * @license Copyright 2012 Dillen Meijboom under the Apache license version 2.0 (http://apache.org/licenses/LICENSE-2.0)
 * @author Dillen Meijboom <info@dillenm.nl>
 * @package System.Library
 */
class Dmf_Benchmark
{
    /**
     * Marks
     *  
     * @var array 
     */
    private $_marks = array();
    
    /**
     * All benchmark instances
     * 
     * @var array 
     */
    private static $_instances = array();
    
    /**
     * Get benchmark instance
     * 
     * @param string $name 
     */
    public static function getInstance( $name )
    {
        return ( isset( self::$_instances[ $name ] ) ? self::$_instances[ $name ] : null );
    }
    
    /**
     * Constructor
     * 
     * @param null|string $name 
     */
    public function __construct( $name = null )
    {
        if ( $name !== null )
        {
            self::$_instances[ $name ] = $this;
        }
    }
    
    /**
     * Set mark
     * 
     * @param string $name 
     */
    public function mark( $name )
    {
        $this->_marks[ $name ] = array(
            'time'      => microtime( true ),
            'memory'    => memory_get_usage()
        );
    }
    
    /**
     * Calculate time between two marks
     * 
     * @param string $mark_x
     * @param string $mark_y
     * @param string $format
     * @return int|boolean 
     */
    public function time( $mark_x, $mark_y, $format = 's' )
    {
        if ( ! isset( $this->_marks[ $mark_x ] ) || ! isset( $this->_marks[ $mark_y ] ) )
        {
            return false;
        }
        
        $time = $this->_marks[ $mark_y ]['time'] - $this->_marks[ $mark_x ]['time'];
        
        switch( $format )
        {
            case 'micro':
                return $time * 1000 * 1000;
            break;
            case 'ms':
                return $time * 1000;
            break;
            default:
                return $time;
            break;
        }
    }
    
    /**
     * Calculate memory usage between two marks
     * 
     * @param string $mark_x
     * @param string $mark_y
     * @param string $format
     * @return int|boolean
     */
    public function memory( $mark_x, $mark_y, $format = 'b' )
    {
        if ( ! isset( $this->_marks[ $mark_x ] ) || ! isset( $this->_marks[ $mark_y ] ) )
        {
            return false;
        }
        
        $memory = $this->_marks[ $mark_y ]['memory'] - $this->_marks[ $mark_x ]['memory'];
        
        switch( $format )
        {
            case 'gb':
                return $memory / 1024 / 1024 / 1024;
            break;
            case 'mb':
                return $memory / 1024 / 1024;
            break;
            case 'kb':
                return $memory / 1024;
            break;
            default:
                return $memory;
            break;
        }
    }
}